#include "utils.h"

// Stack is used so that a beginTimer/endTimer pair can be called inside another
// beginTimer/endTimer pair
std::stack<clock_t> Timer::startTimes;
std::stack<clock_t> Timer::endTimes;

void beginTimer()
{
	Timer::startTimes.push(clock());
}

void endTimer()
{
	Timer::endTimes.push(clock());
}

float getTime()
{
	clock_t startTime = Timer::startTimes.top(); Timer::startTimes.pop();
	clock_t endTime = Timer::endTimes.top(); Timer::endTimes.pop();
	clock_t diff = endTime - startTime;
	return ((float)diff / (float)CLOCKS_PER_SEC);
}

// Basically some C++ versions of atoi/atof, if you're used to using those
// Versions using both strings and stringstreams provided so the functions
// can also work when using streams
int toInt(const std::string &str)
{
	std::istringstream iss(str);
	return toInt(iss);
}

int toInt(std::istringstream &iss)
{
	int i = 0;
	if ((iss >> i).fail())
		throw std::runtime_error("Unable to convert str to int");
	return i;
}

float toFloat(const std::string &str)
{
	std::istringstream iss(str);
	return toFloat(iss);
}

float toFloat(std::istringstream &iss)
{
	float f = 0.0f;
	if ((iss >> f).fail())
		throw std::runtime_error("Unable to convert str to float");
	return f;
}

bool cmp_edge (const Edge &i, const Edge &j)
{
	if (i.cost < j.cost)
		return true;
		
	return false;
}


// There are a lot of different ways to tokenize strings in C++, the easiest way
// is to not bother with tokenizing at all and just read the data directly from
// the stream and check if it failed, this way is much slower but for anyone
// used to strtok, this would be a rough C++ equivalent
std::vector<std::string> tokenize(std::string str, std::string tokens)
{
	for (size_t i = 0; i < str.length(); i++)
		for (size_t j = 0; j < tokens.length(); j++)
			if (str[i] == tokens[j])
				str[i] = ' ';

	std::stringstream sstr(str);

	std::istream_iterator<std::string> it(sstr);
	std::istream_iterator<std::string> end;

	std::vector<std::string> results(it, end);
	return results;
}

// This function actually returns the length squared to avoid performing an sqrt
// operation, so I renamed it to getLengthSq
float getLengthSq(Point p1, Point p2)
{
	return pow(p2.x - p1.x, 2) + pow(p2.y - p1.y, 2);
}
